<?php

namespace app\common\model;

use app\common\BaseModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\Model;

class User extends BaseModel
{
    public static $fieldTypes = [
        'id' => 'number',
        'email' => 'string',
        'status' => 'number',
        'created_at' => 'date',
        'register_time' => 'date',
        'login_time' => 'date',
        'login_ip' => 'string',
    ];
    /**
     * 用户登录
     * @param $data
     * @return mixed
     * @throws Exception
     */
    public static function login($data)
    {
        $curTime = time();
        $datetime = date('Y-m-d H:i:s');
        $email = $data['email'];
        $password = $data['password'];
        $max_fail_num = config('set.login_limited.pwd_fail_num');
        $every_second = config('set.login_limited.every_second');

        if (!$modelRecord = self::findByEmail($email)) {
            throw new Exception('邮箱不存在');
        }

        if($modelRecord->status != self::ENABLED_STATUS){
            throw new Exception('当前邮箱已被禁用，请联系管理员处理。');
        }

        $last_fail_time = !empty($modelRecord->last_fail_time) ? strtotime($modelRecord->last_fail_time) : 0;

        if($modelRecord->failnum >= $max_fail_num && $curTime - $last_fail_time <= $every_second) {
            throw new Exception('超过最大失败次数，请稍后再试');
        }

        if (!self::verifyPassword($password, $modelRecord->encrypt_password)) {
            //超过最大时间限制，重置失败次数
            if($curTime - $last_fail_time > $every_second) {
                $modelRecord->failnum = 1;
            }else{
                $modelRecord->failnum += 1;
            }

            $modelRecord->last_fail_time = $datetime;
            $modelRecord->save();
            throw new Exception('密码错误');
        }

        $modelRecord->loginnum += 1;
        $modelRecord->encrypt_password = self::encryptPassword($password);
        $modelRecord->last_time = !empty($modelRecord->login_time) ? $modelRecord->login_time : $datetime;
        $modelRecord->login_time = $datetime;
        $modelRecord->login_ip = request()->ip();
        $modelRecord->save();
        return $modelRecord;
    }

    /**
     * 用户注册
     * @param $data
     * @return User|array|mixed|Model
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public static function register($data)
    {
        $datetime = date('Y-m-d H:i:s');

        if (self::findByEmail($data['email'])) {
            throw new Exception('邮箱已存在');
        }

        return self::insertGetId([
            'email' => $data['email'],
            'encrypt_password' => self::encryptPassword($data['password']),
            'status' => self::ENABLED_STATUS,
            'login_ip' => request()->ip(),
            'register_time' => $datetime,
        ]);
    }

    /**
     * 保存数据
     * @param $data
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public static function saveData($data)
    {
        if(empty($data['id'])) {
            throw new Exception('用户ID不能为空');
        }else{
            if(!$modelRecord = self::findById($data['id'])) {
                throw new Exception('用户不存在');
            }

            if(!isset($data['status'])) {
                throw new Exception('用户状态不能为空');
            }

            $modelRecord->status = $data['status'];
            $modelRecord->save();
        }
    }

    /**
     * 密码加密
     * @param $password
     * @return false|string|null
     */
    public static function encryptPassword($password)
    {
        return password_hash($password, PASSWORD_BCRYPT);
    }

    /**
     * 验证密码
     * @param $password
     * @param $hash
     * @return bool
     */
    public static function verifyPassword($password, $hash)
    {
        return password_verify($password, $hash);
    }

    /**
     * 根据ID查询用户
     * @param $id
     * @return BaseModel|User|array|mixed|Model|null
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function findById($id)
    {
        return self::where(['id' => $id])->find();
    }

    /**
     * 根据邮箱查询用户
     * @param $email
     * @return User|array|mixed|Model|null
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function findByEmail($email)
    {
        return self::where(['email' => $email])->find();
    }
}